package com.abing.starry.strategy.login;

import cn.hutool.core.lang.Validator;
import com.abing.starry.common.ErrorCode;
import com.abing.starry.constant.RedisKeyConstant;
import com.abing.starry.exception.BusinessException;
import com.abing.starry.exception.ThrowUtils;
import com.abing.starry.model.entity.UserEntity;
import com.abing.starry.model.request.user.UserLoginRequest;
import com.abing.starry.service.UserService;
import com.abing.starry.util.EncryptUtils;
import com.abing.starry.util.TokenUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.Objects;

import static com.abing.starry.constant.RedisKeyConstant.LOGIN_CAPTCHA;
import static com.abing.starry.constant.UserConstant.USER_LOGIN_STATE;

/**
 * @Author CaptainBing
 * @Date 2024/8/28 9:35
 * @Description 账号密码登录
 */
@LoginTypeConfig(loginType = LoginTypeEnum.PASSWORD)
@RequiredArgsConstructor
public class PasswordLoginStrategy implements LoginStrategy {

    private final StringRedisTemplate stringRedisTemplate;

    private final UserService userService;

    @Override
    public String doLogin(UserLoginRequest userLoginRequest) {

        // 校验验证码
        String loginCaptchaKey = RedisKeyConstant.getRedisKey(LOGIN_CAPTCHA, userLoginRequest.getLoginCaptchaKey());
        String loginCaptcha = stringRedisTemplate.opsForValue().get(loginCaptchaKey);
        ThrowUtils.throwIf(StringUtils.isEmpty(loginCaptcha), ErrorCode.PARAMS_ERROR, "验证码已过期");
        boolean isVerify = loginCaptcha.equalsIgnoreCase(userLoginRequest.getLoginCaptchaCode());
        ThrowUtils.throwIf(!isVerify, ErrorCode.PARAMS_ERROR, "验证码错误");

        // 校验账号密码
        String userAccount = userLoginRequest.getUserAccount();
        String userPassword = userLoginRequest.getUserPassword();

        if (StringUtils.isAnyEmpty(userAccount, userPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        ThrowUtils.throwIf(!Validator.isEmail(userAccount), ErrorCode.PARAMS_ERROR, "邮箱格式不合法");
        UserEntity currentUser = userService.getOne(Wrappers.lambdaQuery(UserEntity.class)
                                                     .eq(UserEntity::getUserAccount, userAccount));
        if (Objects.isNull(currentUser)){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        String encryptUserPassword = EncryptUtils.genUserPassword(userPassword);
        if (!encryptUserPassword.equals(currentUser.getUserPassword())){
            throw new BusinessException(ErrorCode.OPERATION_ERROR,"密码错误");
        }
        String token = TokenUtils.genToken(currentUser);
        // token 存入缓存中 USER_LOGIN_STATE:id
        stringRedisTemplate.opsForValue().set(USER_LOGIN_STATE + currentUser.getId(), token);
        return token;
    }
}
